﻿using System;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Collections.Generic;
using System.Security.Cryptography;

namespace EHSubmit.Util
{
    /// <summary>
    /// 网站常用函数
    /// </summary>
    public class WebHelper
    {

        /// <summary>
        /// 获得字符串的MD5值(16位)
        /// </summary>
        /// <param name="text">待加密的字符串</param>
        /// <returns>原字符串的MD5值</returns>
        public static string GetMD5(string text)
        {
            if (text == null)
            {
                return string.Empty;
            }

            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(text)), 4, 8);
            t2 = t2.Replace("-", "");
            return t2.ToLower();
        }

        /// <summary>
        /// 验证email地址是否合法
        /// </summary>
        /// <param name="strIn">待验证的email</param>
        /// <returns>验证结果</returns>
        public static bool IsValidEmail(string strIn)
        {
            // Return true if strIn is in valid e-mail format.
            const string strPattern = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            return Regex.IsMatch(strIn, strPattern);
        }

        /// <summary>
        /// 替换字符串中的脚本标记"<>"为对应的HTML标记&lt;&gt;
        /// </summary>
        /// <param name="strInput">输入字符串</param>
        /// <returns>输出字符串</returns>
        public static string NoScript(string strInput)
        {
            if (string.IsNullOrEmpty(strInput))
                return string.Empty;
            if (strInput.IndexOf('<') >= 0)
                strInput = strInput.Replace("<", "&lt;");
            if (strInput.IndexOf('>') >= 0)
                strInput = strInput.Replace(">", "&gt;");
            return strInput;
        }

        /// <summary>
        /// 将相对URL转化为绝对URL，用于无法访问Page对象的情形。
        /// </summary>
        /// <param name="strRelativeURL">以~/开有的URI地址。</param>
        /// <returns></returns>
        public static string ResolveRelURL(string strRelativeURL)
        {
            strRelativeURL = strRelativeURL.TrimStart("~".ToCharArray());
            if (strRelativeURL.StartsWith("/"))
                return GetAppRoot() + strRelativeURL.Substring(1);
            return new Literal().ResolveClientUrl(strRelativeURL);
        }

        /// <summary>
        /// 获得应用程序的根路径URL。
        /// 如果在web.config中定义了"site.domain", 则使用之。
        /// </summary>
        /// <returns>the root path of this web app</returns>
        public static string GetAppRoot()
        {
            string _app_root = ConfigurationManager.AppSettings["site.domain"] as string;
            if (string.IsNullOrEmpty(_app_root) == false)
                return _app_root.EndsWith("/") ? _app_root : _app_root + "/";
            return new Literal().ResolveClientUrl("~/");
        }

        /// <summary>
        /// 计算两个DateTime的差值的绝对值，然后以适当的文字描述返回。
        /// 例如：2年，3个月，1个星期等。
        /// </summary>
        /// <param name="t1">第一个时间</param>
        /// <param name="t2">第二个时间</param>
        /// <param name="bShortFormat">当相差只有几秒的时候是否返回详细的秒数。一般指定为false。</param>
        /// <returns>时间差的字符串表示。</returns>
        public static string TimeDuration2String(DateTime t1, DateTime t2, bool bShortFormat)
        {
            TimeSpan ts = (t1 - t2);
            ts = ts.Duration();
            int iDays = Convert.ToInt32(ts.TotalDays);
            int iHours = Convert.ToInt32(ts.TotalHours);
            int iMinutes = Convert.ToInt32(ts.TotalMinutes);
            if (iDays > 0)
            {
                // how many years ?
                if (iDays / 365 >= 1)
                {
                    return (iDays / 365) + "年";
                }
                // months ?
                if (iDays / 30 >= 1)
                {
                    return (iDays / 30) + "个月";
                }
                // weeks ?
                if (iDays / 7 >= 1)
                {
                    return (iDays / 7) + "星期";
                }
                // days ?
                return iDays + "天";
            }
            StringBuilder sbSpan = new StringBuilder();
            if (iHours > 0)
            {
                sbSpan.Append(iHours % 24).Append("小时");
                return sbSpan.ToString();
            }
            if (iMinutes > 0)
            {
                sbSpan.Append(iMinutes % 60).Append("分钟");
                return sbSpan.ToString();
            }
            if (bShortFormat && ts.TotalSeconds <= 60.0)
                return "约1分钟";
            return ts.TotalSeconds + "秒";
        }


        /// <summary>
        /// 将字符串按照指定的长度靠左对齐，如果指定的长度大于字符串本身的长度，则截断并将填充字符串追加到末尾；否则返回原字符串。
        /// </summary>
        /// <param name="strInput">输入字符串</param>
        /// <param name="iTotalWidth">输出字符串的长度（包含填充字符串计算在内）</param>
        /// <param name="strFill">填充字符串</param>
        /// <returns>原输入字符串的一部分+填充字符串；或者原字符串+填充字符串</returns>
        public static string StringLeftAlign(string strInput, int iTotalWidth, string strFill)
        {
            if (string.IsNullOrEmpty(strInput))
                return strInput;
            int _fillLength = 0;
            foreach (char ch in strFill)
                if (ch < 256) _fillLength++; else _fillLength += 2;
            iTotalWidth *= 2;
            int i;
            for (i = 0, iTotalWidth -= _fillLength; i < strInput.Length; i++)
            {
                if (strInput[i] < 256) iTotalWidth--; else iTotalWidth -= 2;
                if (iTotalWidth == 0) break; else if (iTotalWidth < 0) { i--; break; }
            }
            if (i + 1 >= strInput.Length) return strInput;
            return strInput.Substring(0, Math.Min(strInput.Length, i + 1)) + strFill;
        }


        /// <summary>
        /// 同StringLeftAlign(input, totalwidth, fill)，只是它不使用填充字符串。
        /// </summary>
        /// <param name="oInput"></param>
        /// <param name="iTotalWidth"></param>
        /// <returns></returns>
        public static string StringLeftAlign(object oInput, int iTotalWidth)
        {
            if (oInput == null)
                throw new ArgumentNullException("oInput");
            return StringLeftAlign(oInput.ToString(), iTotalWidth, String.Empty);
        }

        /// <summary>
        /// 将字符串中的HTML标记去掉"<>"
        /// </summary>
        /// <param name="strInput"></param>
        /// <returns></returns>
        public static string RemoveHtmlTags(string strInput)
        {
            const string pattern = "<[^>]*>|<[\\w\\d]*";
            return Regex.Replace(strInput, pattern, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
        }

        /// <summary>
        /// 安全的int转换,转换失败时返回默认值
        /// </summary>
        /// <param name="o">要转换的对象</param>
        /// <param name="iDefault">转换失败时的默认值</param>
        /// <returns>转换后的值</returns>
        public static int IntSafeConvert(object o, int iDefault)
        {
            if (o == null)
                return iDefault;
            string _s = o.ToString().Trim();
            if (_s.Length <= 0)
                return iDefault;
            int res = iDefault;
            return int.TryParse(_s, out res) ? res : iDefault;
        }
    }
}